﻿using Abp.AspNetCore.Mvc;
using Abp.Authorization;
using Abp.Domain.Entities;
using Abp.Domain.Repositories;
using Abp.Runtime.Session;
using ALEXFW.Authorization;
using ALEXFW.BasicModel;
using ALEXFW.StudentGeneralInfo.Dto;
using ALEXFW.TeacherGeneralInfo.Dto;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ALEXFW.TeacherGeneralInfo
{
    [AbpAuthorize(PermissionNames.Pages_Manager)]
    public class TeacherGeneralInfoAppService : ALEXFWAppServiceBase, ITeacherGeneralInfoAppService
    {
        private IAbpSession _session;
        private IRepository<Teacher, Guid> _teacherContext;
        private IRepository<Exercise, Guid> _exerciseContext;
        private IRepository<ApplyRecord, Guid> _applyRecordContext;
        private IRepository<TopicRepository, Guid> _topicContext;
        private IRepository<Group, Guid> _groupContext;
        private IRepository<Category, Guid> _categoryContext;
        private IRepository<College, Guid> _collegeContext;
        private IRepository<Student, Guid> _studentContext;

        public TeacherGeneralInfoAppService(
             IAbpSession session,
             IRepository<Teacher, Guid> teacherContext,
             IRepository<Exercise, Guid> exerciseContext,
             IRepository<ApplyRecord, Guid> applyRecordContext,
             IRepository<TopicRepository, Guid> topicContext,
             IRepository<Group, Guid> groupContext,
             IRepository<Category, Guid> categoryContext,
            IRepository<College, Guid> collegeContext,
            IRepository<Student, Guid> studentContext


            )
        {
            _session = session;
            _teacherContext = teacherContext;
            _exerciseContext = exerciseContext;
            _applyRecordContext = applyRecordContext;
            _topicContext = topicContext;
            _groupContext = groupContext;
            _categoryContext = categoryContext;
            _collegeContext = collegeContext;
            _studentContext = studentContext;
        }

        /// <summary>
        /// 获取老师信息
        /// </summary>
        /// <returns></returns>
        public async Task<TeacherInfoDto> GetTeacherInfo()
        {
            var userID = _session.UserId;
            if (userID != null)
            {
                var teacher = await _teacherContext.SingleAsync(x => x.UserID == userID);

                var result = new TeacherInfoDto
                {
                    Name = teacher.Name,
                    Sex = teacher.Sex,
                    PhoneNumber = teacher.PhoneNumber,
                    Email = teacher.Email,
                    CollegeName = (await _collegeContext.SingleAsync(x => x.Id == teacher.CollegeID)).Name
                };
                return result;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 更改老师信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> UpdateTeacherInfo(TeacherInfoDto input)
        {
            if (input == null) throw new AbpCustomStatusCodeException(204, "请填写要更改的信息");
            var userID = _session.UserId;
            if (userID != null)
            {
                var teacher = await _teacherContext.SingleAsync(x => x.UserID == userID);
                teacher.PhoneNumber = input.PhoneNumber;
                teacher.Email = input.Email;
                var result = await _teacherContext.UpdateAsync(teacher);
                return result != null ? true : false;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 获取类别
        /// </summary>
        /// <returns></returns>
        public async Task<List<CategorysDto>> GetCategory()
        {
            var userID = _session.UserId;
            if (userID != null)
            {
                var categorys = await _categoryContext.GetAllListAsync();
                if (categorys == null && categorys.Count == 0) throw new AbpCustomStatusCodeException(204, "暂无小组类别，请稍后重试");

                return ObjectMapper.Map<List<CategorysDto>>(categorys);
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 获取这个老师所在的组
        /// </summary>
        /// <returns></returns>
        public async Task<List<GroupsDto>> GetGroup()
        {
            var userID = _session.UserId;
            if (userID != null)
            {
                var teacher = await _teacherContext.SingleAsync(x => x.UserID == userID);
                var group = await _groupContext.GetAllListAsync(x => x.TeacherID == teacher.Id);
                if (group == null && group.Count == 0) throw new AbpCustomStatusCodeException(204, "未加入小组，请重试");

                return ObjectMapper.Map<List<GroupsDto>>(group);
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 通过组ID获取申请加入组的申请人信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<List<ApplyInfoDto>> GetApplysForGroup(string id)
        {
            if (string.IsNullOrEmpty(id)) throw new EntityNotFoundException();
            var groupID = Guid.Parse(id);
            var userID = _session.UserId;
            if (userID != null)
            {
                var result = new List<ApplyInfoDto>();
                var applys = await _applyRecordContext.GetAllListAsync(x => x.GroupID == groupID && x.ApplyStatus == ApplyStatus.正在审核);
                foreach (var item in applys)
                {
                    result.Add(new ApplyInfoDto
                    {
                        Id = item.Id,
                        StudentID = item.StudentID,
                        StudentName = (await _studentContext.SingleAsync(x => x.Id == item.StudentID)).Name,
                        ApplyTime = item.ApplyTime
                    });
                }
                return result;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 审核加入组的申请
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> ExamineApply(ApplyInput input)
        {
            if (input ==null) throw new EntityNotFoundException();
            var userID = _session.UserId;
            if (userID != null)
            {
                var apply = await _applyRecordContext.FirstOrDefaultAsync(x => x.Id == input.ID);
                if (apply == null) throw new AbpCustomStatusCodeException(204, "未找到该申请，请重试");
                apply.ApplyStatus = input.isPass == true ? ApplyStatus.审核通过 : ApplyStatus.审核驳回;

                var result = await _applyRecordContext.UpdateAsync(apply);
                return result == null ? false : true;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 创建实习小组
        /// </summary>
        /// <param name="input">小组名，所属类别</param>
        /// <returns></returns>
        public async Task<bool> CreateGroup(TeacherGroupInput input)
        {
            if (input == null) throw new AbpCustomStatusCodeException(204, "请选择小组和小组所属类别");
            var userID = _session.UserId;
            if (userID != null)
            {
                var teacher = await _teacherContext.SingleAsync(x => x.UserID == userID);
                var group = new Group
                {
                    Id = Guid.NewGuid(),
                    Name = input.Name,
                    CategoryID = input.CategoryID,
                    TeacherID = teacher.Id
                };
                var result = await _groupContext.InsertAndGetIdAsync(group);
                return result == null ? false : true;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 通过组ID获取测试
        /// </summary>
        /// <param name="id">组ID</param>
        /// <returns></returns>
        public async Task<List<ExercisesDto>> GetExercises(string id)
        {
            if (string.IsNullOrEmpty(id)) throw new EntityNotFoundException();
            var groupID = Guid.Parse(id);
            var userID = _session.UserId;
            if (userID != null)
            {
                var exercises = await _exerciseContext.GetAllListAsync(x => x.GroupID == groupID);
                return ObjectMapper.Map<List<ExercisesDto>>(exercises);
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 通过测试ID查找题目
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<List<TopicDto>> GetTopicsByExerciseID(string id)
        {
            if (string.IsNullOrEmpty(id)) throw new EntityNotFoundException();
            var exerciseID = Guid.Parse(id);
            var userID = _session.UserId;
            if (userID != null)
            {
                var topics = await _topicContext.GetAllListAsync(x => x.ExerciseID == exerciseID);
                if (topics != null && topics.Count != 0)
                {
                    return ObjectMapper.Map<List<TopicDto>>(topics);
                }
                else
                    return null;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 获取测试并通过分组来筛选
        /// </summary>
        /// <returns></returns>
        public async Task<List<ExerciseByGroupDto>> GetExercisesByGroup()
        {
            var userID = _session.UserId;
            if (userID != null)
            {
                var exercisesByGroup = new List<ExerciseByGroupDto>();
                var teacher = await _teacherContext.SingleAsync(x => x.UserID == userID);
                var exercises = await _exerciseContext.GetAllListAsync(x => x.Issuser == teacher.Id);
                var tmp = exercises.GroupBy(x => x.GroupID).ToList();
                foreach (var item in tmp)
                {
                    var exerciseList = new List<ExercisesDto>();
                    foreach (var exercise in item)
                    {
                        exerciseList.Add(ObjectMapper.Map<ExercisesDto>(exercise));
                    }
                    exercisesByGroup.Add(new ExerciseByGroupDto
                    {
                        GroupID = item.Key,
                        Exercises = exerciseList
                    });
                }
                return exercisesByGroup;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 添加测试
        /// </summary>
        /// <param name="input">测试名，属于哪个组,一组题目</param>
        /// <returns></returns>
        public async Task<bool> IssueExercise(ExerciseInput input)
        {
            if (input == null) throw new EntityNotFoundException();
            var userID = _session.UserId;
            if (userID != null)
            {
                var result = Guid.Empty;
                var exercise = new Exercise();
                var teacher = await _teacherContext.SingleAsync(x => x.UserID == userID);
                exercise = new Exercise
                {
                    Name = input.Name,
                    GroupID = input.GroupID,
                    Issuser = teacher.Id,
                    EndTime = DateTime.Parse(input.EndTime.ToString("yyyy-MM-dd HH:mm")),
                    PublishStatus = false
                };
                if (input.Id == Guid.Empty)
                {
                    exercise.Id = Guid.NewGuid();
                    result = await _exerciseContext.InsertAndGetIdAsync(exercise);
                }
                else
                {
                    exercise.Id = input.Id;
                    result = (await _exerciseContext.UpdateAsync(exercise)).Id;
                }
                if (result != null)
                {
                    _topicContext.Delete(x => x.ExerciseID == result);
                    foreach (var item in input.Topic)
                    {
                        var topic = new TopicRepository
                        {
                            Id = Guid.NewGuid(),
                            Name = item,
                            ExerciseID = result
                        };
                        _topicContext.Insert(topic);
                    }
                    return true;
                }
                else
                    return false;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 更新测试的发布状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<bool> PublishExercise(ExerciseInput input)
        {
            if (input == null) throw new EntityNotFoundException();
            var userID = _session.UserId;
            if (userID != null)
            {
                var exercise = await _exerciseContext.SingleAsync(x => x.Id == input.Id);
                if (exercise != null)
                {
                    exercise.PublishStatus = true;
                    var result = _exerciseContext.UpdateAsync(exercise);
                    return result == null ? false : true;
                }
                return false;
            }
            else
                throw new AbpAuthorizationException();
        }

        /// <summary>
        /// 通过测试ID删除测试
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteExerciseByID(string id)
        {
            try
            {
                if (string.IsNullOrEmpty(id)) throw new EntityNotFoundException();
                var exerciseID = Guid.Parse(id);
                var userID = _session.UserId;
                if (userID != null)
                {
                    await _topicContext.DeleteAsync(x => x.ExerciseID == exerciseID);
                    await _exerciseContext.DeleteAsync(exerciseID);
                    return true;
                }
                else
                    throw new AbpAuthorizationException();
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 通过测试ID删除多个测试
        /// </summary>
        /// <param name="exerciseIDs"></param>
        /// <returns></returns>
        public bool DeleteExercises(List<string> exerciseIDs)
        {
            if (exerciseIDs == null) throw new EntityNotFoundException();
            var userID = _session.UserId;
            if (userID != null)
            {
                foreach (var item in exerciseIDs)
                {
                    var exerciseID = Guid.Parse(item);
                    _exerciseContext.Delete(exerciseID);
                    _topicContext.Delete(x => x.ExerciseID == exerciseID);
                }
                return true;
            }
            else
                throw new AbpAuthorizationException();
        }
    }
}
